1
2
3
4
5
6
7
8
9
10
11
12
// store.js
import Vue from 'vue'
import Vuex from 'vuex'

Vue.use(Vuex);

export const store = new Vuex.Store({
// counter 라는 state 속성을 추가
state: {
counter: 0
},
});
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
// App.vue
computed: {
parentCounter() {
return this.$store.state.counter;
}
},

// Child.vue
computed: {
childCounter() {
return this.$store.state.counter;
}
},

<!-- App.vue -->
<div id="app">
Parent counter : {{ parentCounter }}
<!-- ... -->
</div>

<!-- Child.vue -->
<div>
Child counter : {{ childCounter }}
<!-- ... -->
</div>

getters 사용

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
// store.js (Vuex)
export const store = new Vuex.Store({
state: {
counter: 0
},
getters: {
doubleCounter: function (state) {
return state.counter * 2;
}
}
});

// App.vue
computed: {
doubleCounter() {
return this.$store.getters.doubleCounter;
}
},

// Child.vue
computed: {
doubleCounter() {
return this.$store.getters.doubleCounter;
}
},

mapGetters

1
2
3
4
5
6
7
// App.vue
import { mapGetters } from 'vuex'

// ...
computed: mapGetters({
parentCounter : 'getCounter' // getCounter 는 Vuex 의 getters 에 선언된 속성 이름
}),

주의 mapGetters를 쓰면 다른 computed 속성과 사용 불가, ES6 문법 …을 사용해야 함.

https://babeljs.io/docs/plugins/preset-stage-2/

1
2
3
4
5
6
7
8
9
10
11
// App.vue
import { mapGetters } from 'vuex'

computed: {
...mapGetters([
'getCounter'
]),
anotherCounter() {
// ...
}
}
  • mutations
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
// store.js
export const store = new Vuex.Store({
// ...
mutations: {
addCounter: function (state, payload) {
return state.counter++;
}
}
});

<!-- App.vue -->
<div id="app">
Parent counter : {{ parentCounter }} <br>
<button @click="addCounter">+</button>
<!-- ... -->
</div>

// App.vue

인자 넘길라면

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
// store.js
mutations: {
// payload 가 { value : 10 } 일 경우
addCounter: function (state, payload) {
state.counter = payload.value;
}
}

// App.vue
methods: {
addCounter() {
this.$store.commit('addCounter', 10);
this.$store.commit('addCounter', {
value: 10,
arr: ["a", "b", "c"]
});
}
},
  • mapMutations
1
2
3
4
5
6
7
8
9
10
11
12
13
// App.vue
import { mapMutations } from 'vuex'

methods: {
// Vuex 의 Mutations 메서드 명과 App.vue 메서드 명이 동일할 때 [] 사용
...mapMutations([
'addCounter'
]),
// Vuex 의 Mutations 메서드 명과 App.vue 메서드 명을 다르게 매칭할 때 {} 사용
...mapMutations({
addCounter: 'addCounter' // 앞 addCounter 는 해당 컴포넌트의 메서드를, 뒤 addCounter 는 Vuex 의 Mutations 를 의미
})
}
  • actions : 비동기 처리시, mutations는 동기
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
// store.js
export const store = new Vuex.Store({
mutations: {
addCounter: function (state, payload) {
return state.counter++;
}
},
actions: {
addCounter: function (context) {
// commit 의 대상인 addCounter 는 mutations 의 메서드를 의미한다.
// 상태 변화 추적 위해, mutations의 메서드를 호출해야함.
return context.commit('addCounter');
},
// 서버에서 가져올 데이터도 이곳에.
getServerData: function (context) {
return axios.get("sample.json").then(function() {
// ...
});
},
delayFewMinutes: function (context) {
return setTimeout(function () {
commit('addCounter');
}, 1000);
},
// 인자 넘기기
asyncIncrement: function (context, payload) {
// payload 는 일반적으로 사용하는 인자 명
return setTimeout(function () {
context.commit('increment', payload.by);
}, payload.duration);
}
}
});

vuex-actions

  • mapActions
1
2
3
4
5
6
7
8
9
10
11
// App.vue
import {mapActions} from 'vuex';

export default {
methods: {
...mapActions([
'asyncIncrement',
'asyncDecrement'
])
},
}

Reference